import Cookies from "js-cookie";
import router from "@/router";
import axios from "axios";
import qs from "qs";

const GET_TOKEN_URL = "/user/get_token/";
const REFRESH_TOKEN_URL = "/user/refresh_token/";
const LOGIN_PATH = "/login";
let requestQueue = [],
  isRefreshing = false;

const instance = axios.create({
  baseURL: "/api/",
  timeout: 10000,
  headers: { "Content-Type": "application/json" },
});

instance.interceptors.request.use(
  (config) => {
    config.paramsSerializer = (params) => {
      return qs.stringify(params, { arrayFormat: "repeat" });
    };

    if (!config.url.includes(GET_TOKEN_URL) && !config.url.includes(REFRESH_TOKEN_URL)) {
      config.headers.Authorization = "Bearer " + Cookies.get("access");
    }

    console.info("Send request:", config);
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

instance.interceptors.response.use(
  (response) => {
    return response.data;
  },
  (error) => {
    if (!error.response) return Promise.reject(error);
    console.error("Request error:", error.response);

    if (error.response.status >= 500) {
      alert("服务器错误");
      return Promise.reject(error);
    }

    if (error.response.status == 401 && !error.config.url.includes(REFRESH_TOKEN_URL)) {
      if (isRefreshing) {
        return new Promise((resolve) => {
          requestQueue.push(() => {
            resolve(instance(error.config));
          });
        });
      } else {
        isRefreshing = true;
        return refreshToken()
          .then((data) => {
            Cookies.set("access", data.access);
            requestQueue.forEach((fn) => fn());
            requestQueue = [];

            return instance(error.config);
          })
          .catch((error) => {
            if (error.response.status == 401) {
              redirectLogin();
              alert("令牌过期, 请重新登录");
            }
            return Promise.reject(error);
          })
          .finally(() => {
            isRefreshing = false;
          });
      }
    }

    alert(error.response.data.detail);
    return Promise.reject(error);
  }
);

function refreshToken() {
  return request({ url: REFRESH_TOKEN_URL, method: "post", data: { refresh: Cookies.get("refresh") } });
}

function redirectLogin() {
  requestQueue = [];
  router.push(LOGIN_PATH);
}

export default function request(item) {
  let { data = {} } = item;
  for (let key in data) {
    if (data[key] === undefined) delete data[key];
  }

  return instance(item);
}
